package indi.mozping.util;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author by mozping
 * @Classname Demo
 * @Description TODO
 * @Date 2020/9/15 19:30
 */
public class Demo {

    private static final String ENCODING = "UTF-8";


    private static String testURL = "http://ecs.aliyuncs.com/?Timestamp=2016-02-23T12:46:24Z&Format=XML&AccessKeyId=testid&Action=DescribeRegions&SignatureMethod=HMAC-SHA1&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2014-05-26&SignatureVersion=1.0";

    private static String secreat = "testsecret";

    public static void main(String[] args) throws UnsupportedEncodingException {

        String[] split = testURL.split("[?]");
        System.out.println(split[0]);
        System.out.println(split[1]);
        String params = split[1];
        String[] paramStrings = params.split("&");
        Map<String, String> paramMap = new TreeMap<>();
        for (String ss : paramStrings) {
            String[] kv = ss.split("=");
            paramMap.put(kv[0], kv[1]);
        }
        System.out.println("----------------");
        //1.得到参数键值对，并且是TreeMap排好序的
        for (String k : paramMap.keySet()) {
            System.out.println(k + " -->" + paramMap.get(k));
        }
        //2.对参数值进行编码,编码后放到新的map
        //3.编码后进行拼接,规范化的请求字符串
        Map<String, String> paramMapEncode = new TreeMap<>();
        StringBuffer sb = new StringBuffer();
        for (String k : paramMap.keySet()) {
            sb.append(percentEncode(k)).append("=").append(percentEncode(paramMap.get(k))).append("&");
        }
        String substring = sb.substring(0, sb.length() - 1);
        System.out.println("规范化的请求字符串:" + substring);

        //4.构造成待签名的字符串
        String stringToSign = "GET" + "&" +
                percentEncode("/") + "&" +
                percentEncode(substring);
        System.out.println("构造成待签名的字符串:" + stringToSign);
        System.out.println("构造成待签名的字符串:" + percentEncode(stringToSign));

        //5.计算签名
        String hamcsha1 = hamcsha1(stringToSign.getBytes(), "testsecret&".getBytes());
        System.out.println("签名:" + hamcsha1);


        String encode = Base64.getEncoder().encodeToString("hamcsha1".getBytes("UTF-8"));
        System.out.println(encode);

    }


    private static String percentEncode(String value) throws UnsupportedEncodingException {
        return value != null ? URLEncoder.encode(value, ENCODING)
                .replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
    }


    private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";


    public static String hamcsha1(byte[] data, byte[] key) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(signingKey);
            return byte2hex(mac.doFinal(data));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    //二行制转字符串
    public static String byte2hex(byte[] b) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int n = 0; b != null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1) {
                hs.append('0');
            }
            hs.append(stmp);
        }
        return hs.toString().toUpperCase();
    }


}